<template>
  <div class="address">
    <el-cascader
      clearable
      placeholder="请选择地区"
      :value="selectedOptions"
      :options="areaOptions"
      change-on-select
      @change="handleAreaChange"
    />
    <el-input
      clearable
      v-if="showCommunityInput"
      placeholder="请输入小区名"
      style="width: 180px"
      :maxlength="100"
      :value="value.communityName"
      @input="inputCommunity"
    />
    <el-select
      clearable
      v-if="showCommunitySelector"
      filterable
      value-key="communityName"
      placeholder="请选择小区"
      :value="value.communityId"
      @change="selsetCommunity"
    >
      <el-option
        v-for="item in communityOptions"
        :key="item.communityId"
        :value="item.communityId"
        :label="item.communityName"
      />
    </el-select>
    <el-input
      clearable
      v-if="showBuildingInput"
      placeholder="请输入楼栋号或者单元号"
      style="width: 160px"
      :maxlength="25"
      :disabled="!value.communityId"
      :value="value.buildingName"
      @input="inputBuilding"
    />
    <el-select
      clearable
      v-if="showBuildingSelector"
      :disabled="!value.communityId"
      placeholder="请选择楼栋"
      :value="value.buildingId"
      @change="selectBuilding"
    >
      <el-option
        v-for="item in buildingOptions"
        :key="item.buildId"
        :value="item.buildId"
        :label="item.buildName"
      />
    </el-select>
    <el-input
      clearable
      v-if="showDetailAddress"
      placeholder="请输入详细地址"
      style="width: 250px"
      :maxlength="50"
      :value="value.detailAddress"
      @input="inputdetailAddress"
    />
  </div>
</template>

<script>
import { findCommunityByPage, findAllCommunity, findCommunityById } from '@/api/community'
import { findBuildingByCommunityId } from '@/api/building'
import { getAreaName } from '@/utils'

export default {
  name: 'AddressSelector',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    showCommunityInput: { type: Boolean, default: false },
    showCommunitySelector: { type: Boolean, default: false },
    showBuildingInput: { type: Boolean, default: false },
    showBuildingSelector: { type: Boolean, default: false },
    showDetailAddress: { type: Boolean, default: false },
    value: {
      type: Object,
      default: () => ({
        province: '',
        provinceId: '',
        city: '',
        cityId: '',
        county: '',
        countyId: '',
        communityName: '',
        communityId: '',
        buildingName: '',
        buildingId: '',
        detailAddress: ''
      })
    }
  },
  data() {
    return {
      communityOptions: [],
      buildingOptions: [],
      loading: false
    }
  },
  computed: {
    selectedOptions() {
      const { province, city, county } = this.value
      if (province) {
        const mProvince = this.areaOptions.find(({ label }) => label === province)
        if (city) {
          if (mProvince.children.length === 0) this.setCity(mProvince.value)
          const mCity = mProvince.children.find(({ label }) => label === city)
          if (mCity) {
            if (county) {
              if (mCity.children.length === 0) {
                this.setCounty(mProvince.value, mCity.value)
              }
              const mCounty = mCity.children.find(({ label }) => label === county)
              return mCounty ? [mProvince.value, mCity.value, mCounty.value] : [mProvince.value, mCity.value]
            } else {
              return [mProvince.value, mCity.value]
            }
          } else {
            return [mProvince.value]
          }
        } else {
          return [mProvince.value]
        }
      } else {
        return []
      }
    },
    areaOptions() {
      return this.$store.getters.area
    }
  },
  watch: {
    value(value, oldValue) {
      this.init(value)
    }
  },
  beforeCreate() {
    if (this.$store.getters.area.length === 0) {
      this.$store.dispatch('setProvince')
    }
  },
  async created() {
    this.init(this.value)
  },
  methods: {
    async init(value) {
      const { province, provinceId, city, cityId, county, countyId, communityId } = value

      if (communityId && (!provinceId || !cityId || !countyId) && !this.showCommunityInput) {
        const { community } = await findCommunityById(communityId)
        const { province_id, city_id, county_id } = community

        const { provinceName, cityName, countyName } = await getAreaName(province_id, city_id, county_id)
        const options = {
          province: provinceName,
          city: cityName,
          county: countyName,
          provinceId: province_id,
          cityId: city_id,
          countyId: county_id,
          comnunityName: community.com_name
        }

        this.emitData(options)
      }

      if ((provinceId && !province) || (cityId && !city) || (countyId && !county)) {
        const { provinceName, cityName, countyName } = await getAreaName(provinceId, cityId, countyId)
        const options = {
          province: provinceName,
          city: cityName,
          county: countyName
        }
        this.emitData(options)
      }

      if (this.showCommunitySelector) {
        if (provinceId || cityId || countyId) {
          const { communitys } = await findCommunityByPage({ provinceId, cityId, countyId }, 50, 1)
          this.communityOptions = communitys.map(({ com_name, com_id }) => ({
            communityName: com_name,
            communityId: com_id
          }))
        } else {
          const { communitys } = await findAllCommunity()
          this.communityOptions = communitys.map(({ com_name, com_id }) => ({
            communityName: com_name,
            communityId: com_id
          }))
        }
      }

      if (communityId && this.showBuildingSelector) {
        const { builds } = await findBuildingByCommunityId(communityId)
        this.buildingOptions = builds
      }
    },
    handleAreaChange(val) {
      const { communityId, buildingId } = this.value
      const [provinceCode, cityCode, countyCode] = val
      let options

      if (provinceCode) {
        const province = this.areaOptions.find(({ value }) => value === provinceCode)
        if (province.children.length === 0) this.setCity(provinceCode)

        if (cityCode) {
          const city = province.children.find(value => value.value === cityCode)
          if (city.children.length === 0) this.setCounty(provinceCode, cityCode)

          if (countyCode) {
            const county = city.children.find(({ value }) => value === countyCode)
            options = {
              province: province.label,
              provinceId: province.id,
              city: city.label,
              cityId: city.id,
              county: county.label,
              countyId: county.id
            }
          } else {
            options = {
              province: province.label,
              provinceId: province.id,
              city: city.label,
              cityId: city.id,
              county: '',
              countyId: ''
            }
          }
        } else {
          options = {
            province: province.label,
            provinceId: province.id,
            city: '',
            cityId: '',
            county: '',
            countyId: ''
          }
        }
      } else {
        options = {
          province: '',
          provinceId: '',
          city: '',
          cityId: '',
          county: '',
          countyId: ''
        }
      }

      if (communityId) {
        options.communityId = ''
        options.communityName = ''
      }

      if (buildingId) {
        options.buildingId = ''
        options.buildingName = ''
      }

      this.emitData(options)
    },
    inputCommunity(communityName) {
      this.emitData({ communityName })
    },
    selsetCommunity(communityId) {
      const communityName = communityId
        ? this.communityOptions.find(val => val.communityId === communityId).communityName
        : ''
      this.emitData({ communityId, communityName })
    },
    inputBuilding(buildingName) {
      this.emitData({ buildingName })
    },
    selectBuilding(buildingId) {
      const buildingName = buildingId ? this.buildingOptions.find(val => val.buildId === buildingId).buildName : ''
      this.emitData({ buildingId, buildingName })
    },
    inputdetailAddress(detailAddress) {
      this.emitData({ detailAddress })
    },
    emitData(prop) {
      this.$emit('change', Object.assign({}, this.value, prop))
    },
    async setCity(provinceCode) {
      await this.$store.dispatch('setCity', provinceCode)
    },
    async setCounty(provinceCode, cityCode) {
      await this.$store.dispatch('setCounty', {
        provinceCode,
        cityCode
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.address > div {
  margin-bottom: 10px;
}
</style>
